package com.itcast.lock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class CalculationBusinessLock {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public void lock(String key,String value) {
        // 获取锁
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, value);
        if (lock) {
            // 获取锁成功
            // 执行业务逻辑
            // 释放锁
            redisTemplate.delete(key);
        } else {
            // 获取锁失败
            // 休眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean spinLock(String key,RemainderCount remainderCount) throws InterruptedException {
        // 获取锁
        while(!getLock(key)){
            if(remainderCount.get()<=1){
                return false;
            }
            TimeUnit.SECONDS.sleep(1);
        }

        return true;
    }

    public boolean getLock(String key) {
        // 获取锁
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, "lockvalue");
        if(flag!=null && flag){
            redisTemplate.expire(key,3, TimeUnit.SECONDS);
            return true;
        }else {
            return false;
        }
    }

    @FunctionalInterface
    public interface RemainderCount{
        int get();
    }

}
